#include "Vector.h"
#include "Test.h"
#include <iostream>

class VecTest: public TestCase
{
private:
	template <class T>
	class Print
	{
	public:
		void operator()(T x)
		{
			printf("%f ", x);
		}
	};

	template <>
	class Print<int>
	{
	public:
		void operator()(int x)
		{
			printf("%d ", x);
		}
	};
public:
	template <class T>
	void print (const T& raw, const char* str = NULL) const
	{
		if (str != NULL) printf("%26s: ", str);
		else printf("%-26s: ", "");
		for (int i = 0; i < T::DEMENSION; i ++)
		{
			Print<T::Type> print_func;
			print_func(raw.data[i]);
		}
		printf("\n");
	}

	void testRaw() {
		float4 rv4(3.14f, 1.28f, 2.56f, 1.71f);

		print<float4>(rv4);

		float4* pf4 = new float4(1.1f, 2.2f, 3.3f, 4.4f);

		print(*pf4);

		pf4->x = 5.5;

		print(*pf4);

		int3 ri3;
		ri3.x = 10;
		print(ri3);
	}

	void testVec() {
		vec4 v4;
		print(v4, "none params vector4f");

		v4.x = 1.2f;
		v4.y = 2.4f;
		v4.z = 3.6f;
		vec4 v41 = v4;
		print(v41, "test =");

		vec4 v42(v41);
		print(v42, "test copy constructor");

		float4 f4(1.1f, 2.2f, 3.3f, 4.4f);
		vec4 v43(1.1f, 2.2f, 3.3f, 4.4f);
		//vec4 v43(f4);
		print(v43, "init with params");

		vec4 v44(v43);
		vec4 v45 = v43.det(v44);
		print(v45, "determinate");

		v45 = v44 = v43 = v42;
		print(v45, "test assign");
		print(v44, "test assign");
		print(v43, "test assign");
		print(v42, "test assign");

		vec3 v30(3.3f, 2.2f, 1.1f);
		print(v30, "init vec3 with params");

		vec4 op0(1.1f, 2.2f, 3.3f);
		vec4 op1(1.0f, 1.0f, 1.0f);
// 		vec4 add0 = op0 + op1;
// 		print(op0, "first operator");
// 		print(op1, "second operator");
// 		print(add0, "add result");
// 		vec4 minus = op0 - op1;
// 		print(minus, "minus result");
// 		vec4 multiple = minus * 3;
// 		print(multiple, "multiple result");



		printf("size of vec4 is %d\n", sizeof(vec4));
	}
	void proc() {
		//testRaw();
		testVec();
	}
};